package com.mysher.devlib.uvc;

import com.mvcframework.mvccamera.Camera;
import com.mvcframework.mvccamera.IOperateListener;
import com.mvcframework.mvccamerabase.CameraAttributes;
import com.mvcframework.mvccamerabase.Format;
import com.mvcframework.mvccamerabase.FormatType;
import com.mysher.devlib.uvc.renderer.YuvGLSurfaceView;

public class DocCamera {

    private int vid, pid;
    private UvcCameraDev uvcCameraDev;

    private boolean operate, closeClear;

    private DocCamera() {
    }

    private static DocCamera instance;

    public synchronized static DocCamera getInstance() {
        if (instance == null) {
            instance = new DocCamera();
        }
        return instance;
    }

    /**
     * 注入DocVidPid,配置文件的话后续再重载方法
     *
     * @param vid
     * @param pid
     */
    public void injectDocCamera(int vid, int pid) {
        this.vid = vid;
        this.pid = pid;
    }

    /**
     * 是否在已经插入设备中
     *
     * @return
     */
    public boolean isAttach() {
        return getDocCamera() != null;
    }

    private Camera getDocCamera() {
        Camera[] cameras = UsbCameraMonitor.getInstance().getCameras();
        if (cameras == null) {
            return null;
        }
        for (Camera camera : cameras) {
            if (camera.getVID() == vid && camera.getPID() == pid) {
                return camera;
            }
        }
        return null;
    }

    public int init() {
        boolean attach = isAttach();
        if (!attach) {
            return -1;
        }
        if (uvcCameraDev != null /*&& !uvcCameraDev.isNativeOpen()*/) {
            return -2;
        }
        uvcCameraDev = UsbCameraMonitor.getInstance().createUvcCameraDev(getDocCamera());
        return 0;
    }

    public boolean isOpen(){
        if (uvcCameraDev == null) {
            return false;
        }
        return uvcCameraDev.isOpen();
    }

    public void openDocCamera(OperateListener iOperateListener) {
        if (uvcCameraDev == null) {
            iOperateListener.onResult(-3);
            return;
        }
        if (uvcCameraDev.isNativeOpen()) {
            iOperateListener.onResult(-4);
            return;
        }
        boolean open = uvcCameraDev.isOpen();
        if (open) {
            iOperateListener.onResult(-5);
            return;
        }
        uvcCameraDev.openCamera(new IOperateListener() {
            @Override
            public void OnFinished(boolean b) {
                iOperateListener.onResult(b ? 0 : -6);
            }
        });
    }

    public void setDecode(boolean hasDecode) {
        uvcCameraDev.setDecode(hasDecode);
    }

    /**
     * 优化解码
     *
     * @param leve 1-4
     */
    public void setMjpegDecodeLeve(int leve) {
        uvcCameraDev.setMjpegLevel(leve);
    }

    public void setPreviewListener(PreviewListener listener) {
        uvcCameraDev.setPreviewListener(listener);
    }

    public void removePreviewListener() {
        uvcCameraDev.setPreviewListener(null);
    }



    public void setPreviewStateListener(PreviewStateListener previewStateListener) {
        uvcCameraDev.setPreviewStateListener(previewStateListener);
    }

    public void setPreviewGlSurfaceView(YuvGLSurfaceView yuvGLSurfaceView) {
        uvcCameraDev.setPreviewGLSurfaceView(yuvGLSurfaceView);
    }

    public void removePreviewStateListener() {
        uvcCameraDev.setPreviewStateListener(null);
    }

    public Format[] getAllFormats() {
        return uvcCameraDev.getAllFormats();
    }

    public Format getFormat(FormatType type) {
        return uvcCameraDev.getFormat(type);
    }

    public void startPreview(Format.Resolution resolution, FormatType formatType, OperateListener iOperateListener) {
        if (uvcCameraDev == null) {
            iOperateListener.onResult(-7);
            return;
        }
        if (!uvcCameraDev.isOpen()) {
            iOperateListener.onResult(-8);
            return;
        }
        if (uvcCameraDev.isPreview()) {
            iOperateListener.onResult(-9);
            return;
        }
        uvcCameraDev.startPreview(resolution, formatType, new IOperateListener() {
            @Override
            public void OnFinished(boolean b) {
                iOperateListener.onResult(b ? 0 : -10);
            }
        });
    }

    public void closePreview(OperateListener iOperateListener) {
        if (uvcCameraDev == null) {
            iOperateListener.onResult(-11);
            return;
        }
        if (uvcCameraDev.isPreview()) {
            uvcCameraDev.stopPreview(new IOperateListener() {
                @Override
                public void OnFinished(boolean b) {
                    iOperateListener.onResult(0);
                }
            });
        } else {
            iOperateListener.onResult(-11);
        }
    }

    public void closeCamera() {
        if (uvcCameraDev == null) {
            return;
        }
        operate = true;
        if (uvcCameraDev.isOpen()) {
            uvcCameraDev.closeDevice(new IOperateListener() {
                @Override
                public void OnFinished(boolean b) {
                    if (closeClear) {
                        uvcCameraDev = null;
                        closeClear = false;
                    }
                    operate = false;
                }
            });
        }

    }

    /**
     * 获取摄像头xu pu等相关参数
     *
     * @return CameraAttrInfo 摄像头属性
     */
    public CameraAttrInfo[] getCameraAttributesValues() {
        if (uvcCameraDev == null) {
            return null;
        }
        return uvcCameraDev.getCameraAttributesValues();
    }

    /**
     * @param id    {@link CameraAttrInfo}
     * @param value 设置的值
     */
    public void setCameraAttributesValue(int id, int value) {
        if (uvcCameraDev == null) {
            return;
        }
        uvcCameraDev.setCameraAttributesValue(CameraAttributes.values()[id], value);
    }

    public void resetCameraAttributes(int id) {
        if (uvcCameraDev == null) {
            return;
        }
        uvcCameraDev.resetCameraAttributes(CameraAttributes.values()[id]);
    }

    public void unInit() {
        uvcCameraDev.setPreviewStateListener(null);
        uvcCameraDev.setPreviewListener(null);
        uvcCameraDev.setPreviewGLSurfaceView(null);
        if (!operate) {
            uvcCameraDev = null;
        } else {
            closeClear = true;
        }
    }
}
